package com.cloudbroker.bcs.platform.dav.common.controller;

import com.alibaba.fastjson.JSON;
import com.cloudbroker.bcs.common.constants.BasicErrorCodes;
import com.cloudbroker.bcs.common.util.*;
import com.cloudbroker.bcs.platform.dav.bizapi.constants.HSBCPSFields;
import com.cloudbroker.bcs.platform.dav.common.config.ConfigValues;
import com.cloudbroker.bcs.platform.dav.common.constant.SysContants;
import com.cloudbroker.bcs.platform.dav.common.constant.type.UploadType;
import com.cloudbroker.bcs.platform.dav.common.ext.annotation.SaveLog;
import com.cloudbroker.bcs.platform.dav.common.extservice.store.StoreServiceFactory;
import com.cloudbroker.bcs.platform.dav.common.util.CompressUtil;
import com.cloudbroker.bcs.platform.dav.common.util.FormatUtil;
import com.cloudbroker.bcs.platform.dav.common.util.SessionHelper;
import com.cloudbroker.bcs.platform.dav.common.util.qrcode.QrCodeUtil;

import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.*;

import static com.cloudbroker.bcs.platform.dav.bizapi.constants.HSBCPSErrorCodes.CommonErr.*;

/**
 * Created by xuyn15828 on 2016/3/16.
 */
@Controller
public class FileController {
    private String platform;
    private static final Logger logger = LoggerFactory.getLogger(FileController.class);
    private static final String FILE_NAME_SEPTUM = "_";
    private static final String NO_LOGIN_TOKEN = DigestUtil.MD5(DigestUtil.SHA512("noLogin".getBytes()).getBytes());
    private static String ACCEPT_TYPE_IMG = "img,jpg,bmp,gif";
    
    public static void main(String[] args) {
        System.out.println(NO_LOGIN_TOKEN);
    }
    
    /*@Resource
    private FileT2BizService fileT2;*/
    
    @ResponseBody
    @RequestMapping("/func_file_upload")
    public Map<String, Object> uploadFile(MultipartHttpServletRequest request) {
        
        try {
            logger.error("upload parameter : " + JSON.toJSONString(request.getParameterMap()));
            String accessToken = request.getParameter(HSBCPSFields.USER_TOKEN);
            String accessTokenKey = SessionHelper.getInstance().getAccess_tokenKey(accessToken);
            if (!NO_LOGIN_TOKEN.equals(accessToken) && !SessionHelper.getInstance().exist(accessTokenKey)) {
                return VOUtil.genErrorResult(BasicErrorCodes.NOT_LOGGED, "未登录");
            }
            MultipartFile multipartFile = request.getFile(HSBCPSFields.FILE);
            String type = request.getParameter(HSBCPSFields.TYPE);
            String fileMark = ValueUtil.getString(request.getParameter(HSBCPSFields.FILE_MARK), "");
            if (null == multipartFile || multipartFile.getSize() == 0) {
                return VOUtil.genErrorResult(FILE_TRANS_ERROR, "文件传输失败");
            } else if (!UploadType.typeExists(type)) {
                return VOUtil.genErrorResult(UPLOAD_FILE_TYPE_ERROR, "文件类型不存在");
            }
            Set<String> acceptFormatSet = UploadType.collectType(type);
            String fileType = IOUtil.getFileType(multipartFile.getInputStream());
            if (!acceptFormatSet.contains(fileType)) {
                return VOUtil.genErrorResult(UPLOAD_FILE_TYPE_ERROR, "文件上传仅支持 : " + acceptFormatSet + "后缀格式");
            }
            if (ACCEPT_TYPE_IMG.contains(fileType) && multipartFile.getSize() > 2097152) {
                return VOUtil.genErrorResult(UPLOAD_FILE_TYPE_ERROR, "图片大小不能超过2M");
            }
            
            String classpath = EnvironmentUtils.getClasspathRoot();
            byte[] b = FormatUtil.wavToMp3(multipartFile.getInputStream(), fileType, classpath);
            InputStream ips = IOUtil.mark(IOUtil.bytesToStream(b));
            fileType = IOUtil.getFileType(IOUtil.reset(ips));
            
            String filename = UUID.randomUUID().toString().replaceAll("-", "");
            filename = fileType + FILE_NAME_SEPTUM + filename;
            
            b = CompressUtil.compress(ips, (long) b.length, fileType, type, classpath);
            StoreServiceFactory.getInstance().getStoreService().uploadFile(filename, b);
            Map<String, Object> resMap = new HashMap<>();
            resMap.put(HSBCPSFields.FILE_MARK, fileMark);
            resMap.put(HSBCPSFields.OSS_ID, filename);
            resMap.put(HSBCPSFields.OSS_PREFIX, ConfigValues.getInterfaceOssAddr());
            resMap.put(HSBCPSFields.FORMAT, fileType);
            resMap.put(HSBCPSFields.SIZE, b.length);
            return VOUtil.setSuccessResult(resMap);
        } catch (Exception e) {
            logger.error("upload file error ", e);
        }
        return VOUtil.genCommonErrorResult();
    }
    
    @RequestMapping("/func_file_download/{file_name}/{access_token}")
    public void downloadFile(@PathVariable("file_name") String file_name,
            @PathVariable("access_token") String access_token, HttpServletResponse response) throws IOException {
        OutputStream ops = response.getOutputStream();
        InputStream ips = null;
        try {
            //            SessionHelper sessionHelper = SessionHelper.getInstance();
            //            String accessTokenKey = sessionHelper.getAccess_tokenKey(access_token);
            //            if (!NO_LOGIN_TOKEN.equals(access_token) && !sessionHelper.exist(accessTokenKey)) {
            //                String downloadIgnoreCheckFilename = ConfigValues.getDownloadIgnoreCheckFilename();
            //                Set<String> filenameSet = new HashSet<>(Arrays.asList(downloadIgnoreCheckFilename.split(",")));
            //                if (!filenameSet.contains(file_name)) {
            //                    ops.write(JSON.toJSONString(VOUtil.genErrorResult(BasicErrorCodes.NOT_LOGGED, "未登录或已超时"))
            //                            .getBytes("utf-8"));
            //                    return;
            //                }
            //            }
            ips = StoreServiceFactory.getInstance().getStoreService().downloadFile(file_name);
            if (ips == null) {
                ops.write(JSON.toJSONString(VOUtil.genErrorResult(FILE_NOT_FOUND, "文件不存在")).getBytes("UTF-8"));
                return;
            }
            IOUtils.copy(ips, ops);
        } catch (Exception e) {
            logger.error("download file error ", e);
        } finally {
            IOUtil.close(ips);
            IOUtil.close(ops);
        }
    }
    
    public String getPlatform() {
        return platform;
    }
    
    public void setPlatform(String platform) {
        this.platform = platform;
    }
    
    /**
     * 二维码生成
     * @param request
     * @param jsonpcallback
     * @return
     */
    @ResponseBody
    @RequestMapping("/func_qrcode_generate")
    @SaveLog(remark = "二维码生成")
    public Map<String, Object> funcQrcodeGenerate(HttpServletRequest request, String jsonpcallback) {
        String customerId = request.getParameter(HSBCPSFields.CUSTOMER_ID);
        if (customerId == null || "".equals(customerId)) {
            customerId = SysContants.UPLOAD_WITHOUT_CUSTOMERID;
        }
        /*读取生成内容*/
        String content = request.getParameter("content");
        InputStream ips = null;
        if (StringUtil.isEmpty(content)) {
            return VOUtil.genErrorResult("二维码内容不能为空");
        }
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        
        try {
            BufferedImage bufferedImage = QrCodeUtil.createImage(content, null, true);
            ImageIO.write(bufferedImage, "jpg", byteArrayOutputStream);
            byte[] b = byteArrayOutputStream.toByteArray();
            String classpath = EnvironmentUtils.getClasspathRoot();
            return uploadFileFromBytes(b, ips, "img", customerId, "", classpath);
            
        } catch (IOException e) {
            logger.error("write bufferedImage to byteArrayOutputStream error ", e);
        } finally {
            IOUtil.close(byteArrayOutputStream);
            IOUtil.close(ips);
        }
        return VOUtil.genCommonErrorResult();
    }
    
    private Map<String, Object> uploadFileFromBytes(byte[] b, InputStream ips, String type, String customerId,
            String fileMark, String classpath) {
        ips = IOUtil.mark(IOUtil.bytesToStream(b));
        String fileType = IOUtil.getFileType(IOUtil.reset(ips));
        
        String filename = UUID.randomUUID().toString().replaceAll("-", "");
        String secret = type.equals("idcard") ? "1" : "0";
        filename = customerId + FILE_NAME_SEPTUM + fileType + FILE_NAME_SEPTUM + secret + FILE_NAME_SEPTUM
                + System.currentTimeMillis() + FILE_NAME_SEPTUM + filename.substring(0, 5);
        
        b = CompressUtil.compress(ips, (long) b.length, fileType, type, classpath);
        try {
            StoreServiceFactory.getInstance().getStoreService().uploadFile(filename, b);
        } catch (Exception e) {
            logger.error("upload file error ", e);
        }
        Map<String, Object> resMap = new HashMap<>();
        resMap.put(HSBCPSFields.FILE_MARK, fileMark);
        resMap.put(HSBCPSFields.OSS_ID, filename);
        resMap.put(HSBCPSFields.OSS_PREFIX, ConfigValues.getInterfaceOssAddr());
        resMap.put(HSBCPSFields.FORMAT, fileType);
        resMap.put(HSBCPSFields.SIZE, b.length);
        Map<String, Object> ret = VOUtil.genEmptyResult();
        resMap = VOUtil.setSuccessResult(resMap);
        ret.put("data", resMap);
        return ret;
    }
}
